/**
 * jz-h5-bluetooth 插件主入口
 * 提供与uni-app蓝牙API兼容的接口，自动适配H5和其他平台
 */

import { bluetoothCore } from './utils/core.js'
import { bleDeviceManager } from './managers/device-manager.js'
import { gattServiceManager } from './managers/service-manager.js'
import { 
  isH5Platform,
  isWebBluetoothSupported,
  createError,
  createSuccess,
  checkDeviceBLECompatibility,
  analyzeConnectionError,
  createOptimalRequestOptions,
  getSmartRecommendedServices,
  guessDeviceType,
  parseServicesToUUIDs
} from './utils/utils.js'
import { ERROR_CODES } from './utils/constants.js'

/**
 * 蓝牙插件类
 */
class JZH5Bluetooth {
  constructor() {
    this.isH5 = isH5Platform()
    this.eventListeners = {
      bluetoothAdapterStateChange: [],
      bluetoothDeviceFound: [],
      BLEConnectionStateChange: [],
      BLECharacteristicValueChange: []
    }
    
    // 初始化事件监听
    this._initEventListeners()
  }

  /**
   * 初始化蓝牙适配器
   */
  async openBluetoothAdapter(options = {}) {
    const result = await bluetoothCore.openBluetoothAdapter(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 强制重新初始化蓝牙适配器
   */
  async reopenBluetoothAdapter(options = {}) {
    // 先关闭再重新打开
    await this.closeBluetoothAdapter()
    
    // 强制重新初始化
    const result = await bluetoothCore.openBluetoothAdapter({ ...options, force: true })
    this._handleCallback(result, options)
    return result
  }

  /**
   * 关闭蓝牙适配器
   */
  async closeBluetoothAdapter(options = {}) {
    const result = await bluetoothCore.closeBluetoothAdapter(options)
    
    // 清理所有连接和监听器
    if (result.errCode === ERROR_CODES.OK) {
      bleDeviceManager.reset()
      gattServiceManager.reset()
      bluetoothCore.clearEventListeners()
    }
    
    this._handleCallback(result, options)
    return result
  }

  /**
   * 获取本机蓝牙适配器状态
   */
  async getBluetoothAdapterState(options = {}) {
    const result = await bluetoothCore.getBluetoothAdapterState(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 开始搜寻附近的蓝牙外围设备
   */
  async startBluetoothDevicesDiscovery(options = {}) {
    const result = await bluetoothCore.startBluetoothDevicesDiscovery(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 停止搜寻附近的蓝牙外围设备
   */
  async stopBluetoothDevicesDiscovery(options = {}) {
    const result = await bluetoothCore.stopBluetoothDevicesDiscovery(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 获取在蓝牙模块生效期间所有已发现的蓝牙设备
   */
  async getBluetoothDevices(options = {}) {
    const result = await bluetoothCore.getBluetoothDevices(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * H5平台专用：请求访问蓝牙设备
   */
  async requestBluetoothDevice(options = {}) {
    if (!this.isH5) {
      const result = createError(ERROR_CODES.WEB_BLUETOOTH_NOT_SUPPORTED, 'This method is only available on H5 platform')
      this._handleCallback(result, options)
      return result
    }

    const result = await bluetoothCore.requestDevice(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * H5平台专用：重新请求设备权限（用于解决服务访问权限问题）
   */
  async rerequestBluetoothDevice(deviceId, additionalServices = []) {
    if (!this.isH5) {
      return createError(ERROR_CODES.WEB_BLUETOOTH_NOT_SUPPORTED, 'This method is only available on H5 platform')
    }

    try {
      // 获取原有的授权信息
      const deviceCacheInfo = bluetoothCore.state.devices.get(`${deviceId}_cache_info`)
      const existingServices = deviceCacheInfo ? Array.from(deviceCacheInfo.authorizedServices) : []
      
      // 合并现有服务和新增服务
      const allServices = [...new Set([...existingServices, ...additionalServices])]
      
      // 重新请求设备权限
      const result = await this.requestBluetoothDevice({
        acceptAllDevices: true,
        optionalServices: allServices
      })
      
      if (result.errCode === ERROR_CODES.OK) {
        return result
      }
      
      return result
    } catch (error) {
      console.error('[JZ-H5-Bluetooth] Re-request device failed:', error)
      return createError(ERROR_CODES.FAIL, `重新请求设备权限失败: ${error.message}`)
    }
  }

  /**
   * H5平台专用：使用特定服务UUID请求设备
   */
  async requestBluetoothDeviceWithServices(serviceUuids = [], options = {}) {
    if (!this.isH5) {
      return createError(ERROR_CODES.WEB_BLUETOOTH_NOT_SUPPORTED, 'This method is only available on H5 platform')
    }

    const requestOptions = {
      acceptAllDevices: true,
      optionalServices: parseServicesToUUIDs(serviceUuids),
      ...options
    }
    
    const result = await this.requestBluetoothDevice(requestOptions)
    return result
  }

  /**
   * H5平台专用：智能设备选择（根据设备名称自动推荐服务）
   * @param {string} expectedDeviceName 预期的设备名称（用于智能推荐服务）
   * @param {Object} options 其他选项
   * @returns {Object} 设备选择结果
   */
  async smartRequestBluetoothDevice(expectedDeviceName = '', options = {}) {
    if (!this.isH5) {
      return createError(ERROR_CODES.WEB_BLUETOOTH_NOT_SUPPORTED, 'This method is only available on H5 platform')
    }

    const optimalOptions = createOptimalRequestOptions(expectedDeviceName, options)
    
    let lastError = null
    try {
      const result = await this.requestBluetoothDevice(optimalOptions)
      if (result.errCode === ERROR_CODES.OK) {
        return result
      }
      lastError = result
    } catch (error) {
      lastError = error
    }
    return lastError || createError(ERROR_CODES.FAIL, '智能设备选择失败')
  }

  /**
   * H5平台专用：通用设备选择（包含最常用的服务权限）
   * @param {Object} options 选项
   * @returns {Object} 设备选择结果
   */
  async requestCommonBluetoothDevice(options = {}) {
    if (!this.isH5) {
      return createError(ERROR_CODES.WEB_BLUETOOTH_NOT_SUPPORTED, 'This method is only available on H5 platform')
    }

    // 自动添加常见服务，解决大部分权限问题
    return await this.smartRequestBluetoothDevice('', options)
  }

  /**
   * 检查设备BLE兼容性
   * @param {string} deviceId 设备ID
   * @returns {Object} 兼容性检查结果
   */
  checkDeviceCompatibility(deviceId) {
    if (!this.isH5) {
      return createSuccess({
        compatible: true,
        platform: 'native',
        message: '原生平台支持所有蓝牙设备类型'
      })
    }

    // 从缓存中获取设备对象
    const device = bluetoothCore.state.devices.get(deviceId)
    
    if (!device) {
      return createError(ERROR_CODES.DEVICE_NOT_FOUND, '设备未找到，请先选择设备')
    }

    const compatibilityResult = checkDeviceBLECompatibility(device)
    
    return createSuccess({
      compatible: compatibilityResult.compatible,
      deviceType: compatibilityResult.deviceType,
      reason: compatibilityResult.reason,
      suggestions: compatibilityResult.suggestions,
      deviceInfo: {
        id: device.id,
        name: device.name || '未知设备',
        hasGatt: !!device.gatt
      }
    })
  }

  /**
   * 获取设备兼容性建议
   * @param {string} deviceName 设备名称（可选）
   * @returns {Object} 设备类型和建议信息
   */
  getDeviceCompatibilityAdvice(deviceName = '') {
    const advice = {
      h5Platform: {
        supportedDevices: [
          '智能手环、手表（如小米手环、Apple Watch等）',
          '健康传感器（心率监测器、体温计、血压计等）',
          '智能家居设备（支持BLE的灯泡、开关、传感器等）',
          '运动设备（智能跑鞋、骑行设备等）',
          'BLE信标设备（iBeacon、Eddystone等）',
          '部分游戏手柄（支持BLE的）'
        ],
        unsupportedDevices: [
          '大多数蓝牙耳机、音箱（使用经典蓝牙）',
          '蓝牙键盘、鼠标（多数使用经典蓝牙）',
          '车载蓝牙系统',
          '蓝牙打印机',
          '传统蓝牙音响设备'
        ],
        limitations: [
          'Web Bluetooth API仅支持BLE（低功耗蓝牙）设备',
          '需要HTTPS环境或localhost才能使用',
          '用户必须主动点击触发设备选择（不能自动连接）',
          '某些浏览器可能不完全支持或限制功能'
        ]
      },
      nativePlatform: {
        advantages: [
          '支持经典蓝牙和BLE双模式',
          '可以连接音频设备（耳机、音箱等）',
          '支持后台连接和自动重连',
          '权限控制更灵活',
          '性能更好，功能更完整'
        ]
      }
    }

    // 根据设备名称给出针对性建议
    const deviceLower = deviceName.toLowerCase()
    let specificAdvice = ''
    
    if (deviceLower.includes('airpods') || deviceLower.includes('headphone') || 
        deviceLower.includes('speaker') || deviceLower.includes('audio')) {
      specificAdvice = '检测到音频设备。此类设备通常使用经典蓝牙协议，建议使用原生App平台连接。'
    } else if (deviceLower.includes('watch') || deviceLower.includes('band') || 
               deviceLower.includes('heart') || deviceLower.includes('sensor')) {
      specificAdvice = '检测到智能穿戴或传感器设备。此类设备通常支持BLE连接，适合在H5平台使用。'
    }

         return createSuccess({
       currentPlatform: this.isH5 ? 'h5' : 'native',
       specificAdvice,
       generalAdvice: advice
     })
   }

   /**
    * 获取设备推荐服务
    * @param {string} deviceName 设备名称
    * @returns {Object} 推荐服务信息
    */
   getDeviceRecommendedServices(deviceName = '') {
     const deviceType = guessDeviceType(deviceName)
     const recommendedServices = getSmartRecommendedServices(deviceName)
     
     return createSuccess({
       deviceName,
       deviceType,
       recommendedServices,
       serviceCount: recommendedServices.length,
       description: `为设备类型 "${deviceType}" 推荐 ${recommendedServices.length} 个服务`
     })
   }

   /**
    * 解析服务名称到UUID
    * @param {string|Array} services 服务名称或数组
    * @returns {Object} 解析结果
    */
   parseServices(services) {
     try {
       const uuids = parseServicesToUUIDs(services)
       return createSuccess({
         originalServices: Array.isArray(services) ? services : [services],
         parsedUUIDs: uuids,
         serviceCount: uuids.length
       })
     } catch (error) {
       return createError(ERROR_CODES.FAIL, `服务解析失败: ${error.message}`)
     }
   }

  /**
   * 连接低功耗蓝牙设备
   */
  async createBLEConnection(options = {}) {
    const result = await bleDeviceManager.createBLEConnection(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 重试连接低功耗蓝牙设备
   */
  async retryBLEConnection(options = {}) {
    const { deviceId, maxRetries = 3, retryDelay = 1000 } = options
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      
      const result = await this.createBLEConnection(options)
      
      if (result.errCode === ERROR_CODES.OK) {
        return result
      }
      
      // 如果不是最后一次尝试，等待一段时间后重试
      if (attempt < maxRetries) {
        await new Promise(resolve => setTimeout(resolve, retryDelay))
      } else {
        return createError(ERROR_CODES.CONNECTION_FAIL, `连接失败：已尝试 ${maxRetries} 次，请检查设备状态后重试`)
      }
    }
  }

  /**
   * 断开与低功耗蓝牙设备的连接
   */
  async closeBLEConnection(options = {}) {
    const result = await bleDeviceManager.closeBLEConnection(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 根据uuid获取处于已连接状态的设备
   */
  async getConnectedBluetoothDevices(options = {}) {
    const result = await bleDeviceManager.getConnectedBluetoothDevices(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 获取蓝牙设备所有服务
   */
  async getBLEDeviceServices(options = {}) {
    const result = await gattServiceManager.getBLEDeviceServices(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 获取蓝牙设备某个服务中所有特征值
   */
  async getBLEDeviceCharacteristics(options = {}) {
    const result = await gattServiceManager.getBLEDeviceCharacteristics(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 读取低功耗蓝牙设备的特征值的二进制数据值
   */
  async readBLECharacteristicValue(options = {}) {
    const result = await gattServiceManager.readBLECharacteristicValue(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 向低功耗蓝牙设备特征值中写入二进制数据
   */
  async writeBLECharacteristicValue(options = {}) {
    const result = await gattServiceManager.writeBLECharacteristicValue(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 启用低功耗蓝牙设备特征值变化时的notify功能
   */
  async notifyBLECharacteristicValueChange(options = {}) {
    const result = await gattServiceManager.notifyBLECharacteristicValueChange(options)
    this._handleCallback(result, options)
    return result
  }

  /**
   * 监听蓝牙适配器状态变化事件
   */
  onBluetoothAdapterStateChange(callback) {
    this._addEventListener('bluetoothAdapterStateChange', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.onBluetoothAdapterStateChange(callback)
    }
  }

  /**
   * 取消监听蓝牙适配器状态变化事件
   */
  offBluetoothAdapterStateChange(callback) {
    this._removeEventListener('bluetoothAdapterStateChange', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.offBluetoothAdapterStateChange(callback)
    }
  }

  /**
   * 监听寻找到新设备的事件
   */
  onBluetoothDeviceFound(callback) {
    this._addEventListener('bluetoothDeviceFound', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.onBluetoothDeviceFound(callback)
    }
  }

  /**
   * 取消监听寻找到新设备的事件
   */
  offBluetoothDeviceFound(callback) {
    this._removeEventListener('bluetoothDeviceFound', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.offBluetoothDeviceFound(callback)
    }
  }

  /**
   * 监听低功耗蓝牙连接状态的改变事件
   */
  onBLEConnectionStateChange(callback) {
    this._addEventListener('BLEConnectionStateChange', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.onBLEConnectionStateChange(callback)
    }
  }

  /**
   * 取消监听低功耗蓝牙连接状态的改变事件
   */
  offBLEConnectionStateChange(callback) {
    this._removeEventListener('BLEConnectionStateChange', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.offBLEConnectionStateChange(callback)
    }
  }

  /**
   * 监听低功耗蓝牙设备的特征值变化事件
   */
  onBLECharacteristicValueChange(callback) {
    this._addEventListener('BLECharacteristicValueChange', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.onBLECharacteristicValueChange(callback)
    }
  }

  /**
   * 取消监听低功耗蓝牙设备的特征值变化事件
   */
  offBLECharacteristicValueChange(callback) {
    this._removeEventListener('BLECharacteristicValueChange', callback)
    
    // 原生平台直接使用uni API
    if (!this.isH5) {
      uni.offBLECharacteristicValueChange(callback)
    }
  }

  /**
   * 获取当前平台信息
   */
  getPlatformInfo() {
    return {
      platform: bluetoothCore.platform,
      isH5: this.isH5,
      webBluetoothSupported: this.isH5 ? isWebBluetoothSupported() : false
    }
  }

  /**
   * 获取设备连接状态
   */
  getDeviceConnectionState(deviceId) {
    return bleDeviceManager.getDeviceConnectionState(deviceId)
  }

  /**
   * 检查设备是否已连接
   */
  isDeviceConnected(deviceId) {
    return bleDeviceManager.isDeviceConnected(deviceId)
  }

  /**
   * 获取已缓存的服务列表
   */
  getCachedServices(deviceId) {
    return gattServiceManager.getCachedServices(deviceId)
  }

  /**
   * 获取已缓存的特征值列表
   */
  getCachedCharacteristics(deviceId, serviceId) {
    return gattServiceManager.getCachedCharacteristics(deviceId, serviceId)
  }

  /**
   * 获取设备的授权服务信息
   */
  getDeviceAuthorizedServices(deviceId) {
    if (!this.isH5) {
      return []
    }
    
    const deviceCacheInfo = bluetoothCore.state.devices.get(`${deviceId}_cache_info`)
    return deviceCacheInfo ? Array.from(deviceCacheInfo.authorizedServices) : []
  }

  /**
   * 检查服务是否已授权
   */
  isServiceAuthorized(deviceId, serviceUuid) {
    if (!this.isH5) {
      return true // 非H5平台不需要检查授权
    }
    
    const authorizedServices = this.getDeviceAuthorizedServices(deviceId)
    return authorizedServices.includes(serviceUuid.toLowerCase())
  }

  /**
   * 断开所有连接
   */
  async disconnectAllDevices() {
    try {
      const result = await bleDeviceManager.disconnectAll()
      // 确保返回标准格式的结果对象
      if (!result || typeof result !== 'object') {
        return createSuccess({ message: 'All devices disconnected' })
      }
      return result
    } catch (error) {
      return createError(ERROR_CODES.FAIL, `Disconnect all devices failed: ${error.message}`)
    }
  }

  /**
   * 初始化事件监听器
   */
  _initEventListeners() {
    if (this.isH5) {
      // H5平台监听核心事件
      bluetoothCore.addEventListener('stateChange', (data) => {
        this._triggerEvent('bluetoothAdapterStateChange', data)
      })

      bluetoothCore.addEventListener('deviceFound', (data) => {
        this._triggerEvent('bluetoothDeviceFound', data)
      })

      bluetoothCore.addEventListener('characteristicValueChange', (data) => {
        this._triggerEvent('BLECharacteristicValueChange', data)
      })
    }
  }

  /**
   * 添加事件监听器
   */
  _addEventListener(event, callback) {
    if (this.eventListeners[event]) {
      this.eventListeners[event].push(callback)
    }
  }

  /**
   * 移除事件监听器
   */
  _removeEventListener(event, callback) {
    if (this.eventListeners[event]) {
      const index = this.eventListeners[event].indexOf(callback)
      if (index > -1) {
        this.eventListeners[event].splice(index, 1)
      }
    }
  }

  /**
   * 触发事件
   */
  _triggerEvent(event, data) {
    if (this.eventListeners[event]) {
      this.eventListeners[event].forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error(`Error in ${event} listener:`, error)
        }
      })
    }
  }

  /**
   * 处理回调函数
   */
  _handleCallback(result, options = {}) {
    // 确保result是有效对象
    if (!result || typeof result !== 'object') {
      console.error('[JZ-H5-Bluetooth] Invalid result object:', result)
      result = createError(ERROR_CODES.FAIL, 'Invalid operation result')
    }
    
    // 确保result有errCode属性
    if (typeof result.errCode === 'undefined') {
      console.error('[JZ-H5-Bluetooth] Result missing errCode:', result)
      result.errCode = ERROR_CODES.FAIL
      result.errMsg = result.errMsg || 'Unknown error'
    }
    
    try {
      if (result.errCode === ERROR_CODES.OK) {
        if (options.success) {
          options.success(result)
        }
      } else {
        if (options.fail) {
          options.fail(result)
        }
      }
      
      if (options.complete) {
        options.complete(result)
      }
    } catch (error) {
      console.error('[JZ-H5-Bluetooth] Error in callback handler:', error)
    }
  }
}

// 创建单例实例
const jzH5Bluetooth = new JZH5Bluetooth()

// 导出所有方法以支持不同的使用方式
export const {
  // 蓝牙适配器相关
  openBluetoothAdapter,
  closeBluetoothAdapter,
  getBluetoothAdapterState,
  
  // 设备发现相关
  startBluetoothDevicesDiscovery,
  stopBluetoothDevicesDiscovery,
  getBluetoothDevices,
  requestBluetoothDevice,
  rerequestBluetoothDevice,
  requestBluetoothDeviceWithServices,
  smartRequestBluetoothDevice,
  requestCommonBluetoothDevice,
  
  // BLE连接相关
  createBLEConnection,
  retryBLEConnection,
  closeBLEConnection,
  getConnectedBluetoothDevices,
  
  // GATT服务相关
  getBLEDeviceServices,
  getBLEDeviceCharacteristics,
  readBLECharacteristicValue,
  writeBLECharacteristicValue,
  notifyBLECharacteristicValueChange,
  
  // 事件监听相关
  onBluetoothAdapterStateChange,
  offBluetoothAdapterStateChange,
  onBluetoothDeviceFound,
  offBluetoothDeviceFound,
  onBLEConnectionStateChange,
  offBLEConnectionStateChange,
  onBLECharacteristicValueChange,
  offBLECharacteristicValueChange,
  
  // 工具方法
  getPlatformInfo,
  getDeviceConnectionState,
  isDeviceConnected,
  getCachedServices,
  getCachedCharacteristics,
  getDeviceAuthorizedServices,
  isServiceAuthorized,
  disconnectAllDevices,
  
  // 设备兼容性和服务推荐
  checkDeviceCompatibility,
  getDeviceCompatibilityAdvice,
  getDeviceRecommendedServices,
  parseServices
} = jzH5Bluetooth

// 默认导出插件实例
export default jzH5Bluetooth

// 兼容uni模块安装方式
export const install = (Vue) => {
  Vue.prototype.$bluetooth = jzH5Bluetooth
}
